﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Threading;
using Prism.Mvvm;
using YF_Music.Core.Enums;
using YF_Music.Core.Models;
using YF_Music.Core.Services;

namespace YF_Music.Service
{
  public class MusicPlayerService : BindableBase, IMusicPlayerService
  {
    private readonly MediaPlayer _mediaPlayer = new();
    private readonly DispatcherTimer _progressTimer = new() { Interval = TimeSpan.FromMilliseconds(1000) };

    private ObservableCollection<MusicItem> _playlist = new();
    private int _currentIndex = -1;

    /// <summary>
    /// 获取或设置 当前播放时间
    /// </summary>
    public double CurrentSeconds
    {
      get => _currentPosition.TotalSeconds;
      set
      {
        CurrentPosition = TimeSpan.FromSeconds(value);
        // 同步更新到播放器核心（如 MediaPlayer.Position = CurrentPosition）
        _mediaPlayer.Position = CurrentPosition;
      }
    }

    public TimeSpan CurrentPositionRealTime => _mediaPlayer.Position;

    private TimeSpan _currentPosition;
    /// <summary>
    /// 当前播放位置 1秒一刷新
    /// </summary>
    public TimeSpan CurrentPosition
    {
      get => _currentPosition;
      private set
      {
        if (SetProperty(ref _currentPosition, value))
        {
          RaisePropertyChanged(nameof(CurrentSeconds));
        }
      }
    }

    private MusicItem _currentMusic;
    public MusicItem CurrentMusic
    {
      get => _currentMusic;
      private set
      {
        if (SetProperty(ref _currentMusic, value))
        {
          CurrentMusicChange?.Invoke(value);
        }
      }
    }
    private TimeSpan _totalDuration;
    public TimeSpan TotalDuration
    {
      get => _totalDuration;
      private set
      {
        SetProperty(ref _totalDuration, value);
      }
    }

    public event Action<string> LyricChanged;
    public event Action<MusicItem> CurrentMusicChange;

    private PlayState _playState = PlayState.Stopped;
    public PlayState PlayState
    {
      get => _playState;
      private set
      {
        SetProperty(ref _playState, value);
      }
    }

    public double Volume
    {
      get => _mediaPlayer.Volume * 100;
      set => _mediaPlayer.Volume = Math.Max(0, Math.Min(100, value)) / 100;
    }

    public bool IsMuted
    {
      get => _mediaPlayer.IsMuted;
      set => _mediaPlayer.IsMuted = value;
    }
    private PlayMode playMode = PlayMode.顺序播放;
    public PlayMode PlayMode
    {
      get => playMode;
      set
      {
        SetProperty(ref playMode, value);
      }
    }


    public void ToggleMute() => _mediaPlayer.IsMuted = !_mediaPlayer.IsMuted;

    public void LoadPlaylist(ObservableCollection<MusicItem> playlist, PlaylistSession session)
    {
      _playlist = playlist ?? new();
      _currentIndex = _playlist.Count > 0 ? 0 : -1;
      currentSession = session;
    }

    public void Play(int index = -1)
    {
      if (index >= 0)
      {
        _currentIndex = index;
        if (_currentIndex < 0 || _currentIndex >= _playlist.Count)
          return;

        var item = _playlist[_currentIndex];
        _mediaPlayer.Open(new Uri(item.FilePath, UriKind.RelativeOrAbsolute));
        CurrentMusic = item;
        ResetLyric();
        CurrentPosition = TimeSpan.FromMilliseconds(0);
      }
      if (CurrentMusic != null)
      {
        PlayState = PlayState.Playing;
        _mediaPlayer.Play();
        _progressTimer.Start();
        UpdateCurrent();
      }
    }

    public void Pause()
    {
      _mediaPlayer.Pause();
      _progressTimer.Stop();
      PlayState = PlayState.Paused;
    }

    public void Stop()
    {
      _mediaPlayer.Stop();
      _progressTimer.Stop();
      PlayState = PlayState.Stopped;
    }

    public void PlayNext()
    {
      if (_currentIndex + 1 < _playlist.Count)
        Play(_currentIndex + 1);
      else
      {
        //循环播放
        _currentIndex = 0;
        Play(_currentIndex);
      }
    }

    public void PlayPrevious()
    {
      if (_currentIndex - 1 >= 0)
        Play(_currentIndex - 1);
      else
      {
        Play(_playlist.Count - 1);
      }
    }

    public void SeekForward(TimeSpan interval)
    {
      if (_mediaPlayer.NaturalDuration.HasTimeSpan)
      {
        var newTime = _mediaPlayer.Position + interval;
        _mediaPlayer.Position = newTime < _mediaPlayer.NaturalDuration.TimeSpan ? newTime : _mediaPlayer.NaturalDuration.TimeSpan;
      }
    }
    private PlaylistSession? currentSession;




    public void SeekBackward(TimeSpan interval)
    {
      var newTime = _mediaPlayer.Position - interval;
      _mediaPlayer.Position = newTime < TimeSpan.Zero ? TimeSpan.Zero : newTime;
    }

    public MusicPlayerService()
    {
      _mediaPlayer.MediaEnded += (_, _) =>
      {
        CurrentMusic.PlayCount++;
        currentSession?.MarkDirty();
        PlayNext();
      };

      _progressTimer.Tick += (_, _) =>
      {
        UpdateCurrent();
      };
    }

    private void UpdateCurrent()
    {
      if (_mediaPlayer.NaturalDuration.HasTimeSpan)
      {
        CurrentPosition = _mediaPlayer.Position;
        TotalDuration = _mediaPlayer.NaturalDuration.TimeSpan;
        UpdateLyric(_mediaPlayer.Position);
      }
    }

    // === 歌词支持 ===
    private SortedList<TimeSpan, string> _lyrics = new();
    private IEnumerator<KeyValuePair<TimeSpan, string>> _lyricEnumerator;

    public bool LoadLyric(string lrcPath)
    {
      _lyrics.Clear();
      if (!File.Exists(lrcPath))
        return false;

      var lines = File.ReadAllLines(lrcPath);
      foreach (var line in lines)
      {
        var match = Regex.Match(line, @"\[(\d+):(\d+)\.(\d+)\](.+)");
        if (match.Success)
        {
          var time = new TimeSpan(0, 0, int.Parse(match.Groups[1].Value), int.Parse(match.Groups[2].Value), int.Parse(match.Groups[3].Value) * 10);
          var text = match.Groups[4].Value.Trim();
          _lyrics[time] = text;
        }
      }

      _lyricEnumerator = _lyrics.GetEnumerator();
      _lyricEnumerator.MoveNext();
      return true;
    }

    private void ResetLyric()
    {
      if (_lyrics.Any())
      {
        _lyricEnumerator = _lyrics.GetEnumerator();
        _lyricEnumerator.MoveNext();
      }
    }

    private void UpdateLyric(TimeSpan current)
    {
      if (_lyricEnumerator == null)
        return;

      while (_lyricEnumerator.Current.Key <= current)
      {
        LyricChanged?.Invoke(_lyricEnumerator.Current.Value);
        if (!_lyricEnumerator.MoveNext()) break;
      }
    }

    public bool IsListEqual(ObservableCollection<MusicItem> playlist)
    {
      return playlist.Equals(_playlist);
    }

    public void SetSessionDirty()
    {
      currentSession?.MarkDirty();
    }
  }
}
